/*
 * #%L
 * Client
 * %%
 * Copyright (C) 2011 Ractoc.com
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.ractoc.opengamefinder.client.plugins;

import org.apache.log4j.Logger;

import com.ractoc.opengamefinder.api.messages.ErrorMessage;
import com.ractoc.opengamefinder.api.results.MessageResultsErrorCodes;
import com.ractoc.opengamefinder.api.messages.NetworkMessage;
import com.ractoc.opengamefinder.api.results.NetworkMessageResult;
import com.ractoc.opengamefinder.client.plugins.messages.DisplayScreenMessage;
import com.ractoc.opengamefinder.client.plugins.messages.GuiMessage;
import com.ractoc.opengamefinder.client.plugins.nifty.ScreenType;
import com.ractoc.opengamefinder.client.plugins.results.DisplayScreenMessageResult;
import com.ractoc.pffj.api.BasePlugin;
import com.ractoc.pffj.api.BasePluginMessage;
import com.ractoc.pffj.api.BasePluginMessageResult;
import com.ractoc.pffj.core.PluginController;
import com.ractoc.pffj.core.PluginException;

/**
 * Base plugin for the client. Contains all methods the other plugins have in common.
 * @author ractoc
 * @version 0.1
 */
public abstract class BaseClientPlugin extends BasePlugin {

    private static final String ERROR_PLUGIN_MESSAGE = "Error sending message through the plugin system: ";
    private static final String GUI_PLUGIN = "guiPlugin";
    private static Logger logger = Logger.getLogger(BaseClientPlugin.class.getName());

    /**
     * Default constructor.
     */
    public BaseClientPlugin() {
        super();
    }

    /**
     * Handles switching to the new screen.
     * @param screen The screen to display.
     * @param screenType The screentype to display.
     */
    protected final void displayScreen(final String screen, final ScreenType screenType) {
        BasePluginMessageResult result = new DisplayScreenMessageResult();
        try {
            final DisplayScreenMessage dsMsg = new DisplayScreenMessage();
            dsMsg.setScreenName(screen);
            final GuiMessage guiMsg = new GuiMessage();
            guiMsg.setPayload(dsMsg);
            guiMsg.setType(screenType);
            result = (DisplayScreenMessageResult) PluginController.getCurrentPluginController().processMessage(
                    GUI_PLUGIN, guiMsg);
        } catch (final PluginException e) {
            result.setErrorCode(MessageResultsErrorCodes.INTERNAL_ERROR);
            logger.error(ERROR_PLUGIN_MESSAGE, e);
        }
        if (result.getErrorCode() != MessageResultsErrorCodes.SUCCESS) {
            displayError(result.getErrorCode(), screenType);
        }
    }

    /**
     * Handles displaying an error message on the screen.
     * @param errorCode The code of the error message to display.
     * @param screenType The screen type of the screen.
     */
    protected final void displayError(final Enum errorCode, final ScreenType screenType) {
        final ErrorMessage eMsg = new ErrorMessage();
        eMsg.setErrorCode(errorCode);
        final GuiMessage guiMsg = new GuiMessage();
        guiMsg.setPayload(eMsg);
        guiMsg.setType(screenType);
        try {
            PluginController.getCurrentPluginController().processMessage(GUI_PLUGIN, guiMsg);
        } catch (final PluginException e) {
            logger.error(ERROR_PLUGIN_MESSAGE, e);
        }
    }

    /**
     * Sends a network message to the server.
     * @param result The result of the message sent.
     * @param msg The message to send.
     * @param originPlugin The plugin on the client where the message originated.
     * @param destinationPlugin The plugin on the server the message is intended for.
     * @param secure Is the message to be sent securely.
     * @param reliable Is the message to be sent reliably.
     */
    protected final void sendNetworkMessage(final BasePluginMessageResult result, final BasePluginMessage msg,
            final String originPlugin, final String destinationPlugin, final boolean secure, final boolean reliable) {
        final NetworkMessage nMsg = new NetworkMessage();
        nMsg.setPayload(msg);
        nMsg.setOriginPlugin(originPlugin);
        nMsg.setDestinationPlugin(destinationPlugin);
        nMsg.setSecure(secure);
        nMsg.setReliable(reliable);
        NetworkMessageResult nResult = null;
        try {
            nResult = (NetworkMessageResult) PluginController.getCurrentPluginController().processMessage(
                    "networkPlugin", nMsg);
        } catch (final PluginException e) {
            result.setErrorCode(MessageResultsErrorCodes.INTERNAL_ERROR);
            logger.error(ERROR_PLUGIN_MESSAGE, e);
        }
        if (nResult.getErrorCode() != MessageResultsErrorCodes.SUCCESS) {
            result.setErrorCode(nResult.getErrorCode());
        } else {
            result.setErrorCode(MessageResultsErrorCodes.SUCCESS);
        }
    }

}
